﻿using SFJDService.SocketHandle;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace SFJDService
{
    public class SFJDRun
    {
        static Socket socketMsg;
        static Socket socketUdp;
        static bool serviceRunning = false;

        public SFJDRun()
        {
            OnStart();
        }

        /// <summary>
        /// 启动
        /// </summary>
        protected void OnStart()
        {
            serviceRunning = true;
            Runtime.Initialize();
            //Runtime.isDebugMode = true;
            Runtime.Printf(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + "服务已启动！！！");

            socketMsg = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socketMsg.Bind(new IPEndPoint(IPAddress.Parse(Runtime.myIP), Runtime.portMsg));
            socketMsg.Listen(0);

            new Thread(TcpHandle).Start();
            new Thread(UdpHandle).Start();
            new Thread(() =>
            {
                Thread.Sleep(500);
                if (Runtime.thisUser.UserName != null)
                {
                    Launcher.SendUdp2All(typeof(PH07OnLine).GetDictianaryKey(), Runtime.thisUser.UserName + '♠' + Runtime.version.ToString());
                }
                Thread.Sleep(1000);
                if (Runtime.UsersOnLine.activeUsers.Count < 5)
                {
                    List<string> hostsIp = new LanScanning(Runtime.portMsg).GetActiveHosts();
                    foreach (string ip in hostsIp)
                    {
                        Launcher.SendTcp(typeof(PH07OnLine).GetDictianaryKey(), ip, Runtime.thisUser.UserName + '♠' + Runtime.version.ToString());
                    }
                    Thread.Sleep(1000);
                }
                new SyncData();
                new Synchronization(SynType.Brigade);
                new Synchronization(SynType.Contact);
                new Synchronization(SynType.User);
            }).Start();
        }

        private static void UdpHandle()
        {
            socketUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint edp = new IPEndPoint(IPAddress.Any, Runtime.portUdp);
            socketUdp.Bind(edp);
            EndPoint ep = edp;
            while (serviceRunning)
            {
                try
                {
                    byte[] buff = new byte[Runtime.SocketLenght];
                    int rel = socketUdp.ReceiveFrom(buff, ref ep);
                    new LanHandle(socketUdp, buff);
                }
                catch (Exception e)
                {
                    Runtime.Printf(e.Message);
                }
            }
        }

        private static void TcpHandle()
        {
            while (serviceRunning)
            {
                Socket cSocket = socketMsg.Accept();
                try
                {
                    byte[] tcpIn = new byte[Runtime.SocketLenght];
                    int recl = cSocket.Receive(tcpIn);
                    new LanHandle(cSocket, tcpIn);
                }
                catch (Exception e)
                {
                    Runtime.Printf(e.Message);
                }
            }
        }

        ////////////////////////////////////////////////////////////////////////////
        public void OnStart2()
        {
            Runtime.Printf("服务已启动！！！");
            Runtime.Initialize();

            socketMsg = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socketMsg.Bind(new IPEndPoint(IPAddress.Parse(Runtime.myIP), Runtime.portMsg));
            socketMsg.Listen(0);

            new Thread(TcpHandle2).Start();
            new Thread(UdpHandle2).Start();

            Runtime.Printf("开始监听：" + Runtime.myIP + ":" + Runtime.portMsg + " & " + Runtime.portUdp);
        }

        public void OnStop2()
        {
            if(socketMsg != null && socketMsg.Connected)
                socketMsg.Close();
            if(socketUdp != null && socketUdp.Connected)
                socketUdp.Close();
            Runtime.Printf("服务已关闭！！！");
        }

        private static void UdpHandle2()
        {
            socketUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint edp = new IPEndPoint(IPAddress.Any, Runtime.portUdp);
            socketUdp.Bind(edp);
            EndPoint ep = edp;
            byte[] buff = new byte[Runtime.SocketLenght];
            while (true)
            {
                try
                {
                    int rel = socketUdp.ReceiveFrom(buff, ref ep);
                    new LanHandle(socketUdp, buff);
                }
                catch (Exception e)
                {
                    Runtime.Printf( e.Message);
                }
            }
        }

        private static void TcpHandle2()
        {
            while (true)
            {
                Socket cSocket = socketMsg.Accept();
                try
                {
                    byte[] tcpIn = new byte[Runtime.SocketLenght];
                    int recl = cSocket.Receive(tcpIn);
                    new LanHandle(cSocket, tcpIn);
                }
                catch (Exception e)
                {
                    Runtime.Printf(e.Message);
                }
            }
        }

        private static void RecevieMsg2(object cSocket)
        {
            Socket oneCSocket = (Socket)cSocket;
            while (true)
            {
                try
                {
                    byte[] msgIn = new byte[1024];
                    int recLength = oneCSocket.Receive(msgIn);
                    string rec = Encoding.ASCII.GetString(msgIn, 0, recLength);
                    Runtime.Printf("客户端Local：" + oneCSocket + " 发来消息：" + rec);
                    //oneCSocket.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    if (oneCSocket != null && oneCSocket.Connected)
                    {
                        oneCSocket.Shutdown(SocketShutdown.Both);
                        Thread.Sleep(2000);
                        oneCSocket.Close();
                        break;
                    }
                }
            }
        }
    }
}
